package cn.agiledata.bank.myspace.service;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

import cn.agiledata.bank.audit.logic.AuditStatus;
import cn.agiledata.bank.audit.service.AuditService;
import cn.agiledata.bank.common.dao.AccountTemplateInter;
import cn.agiledata.bank.common.dao.TransactionTemplate;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AuditOperandType;

public class AuthenticateServiceImpl implements AuthenticateService {

	private AccountTemplateInter accountTemplate;

	private TransactionTemplate transactionTemplate;

	private AuditService auditService;

	public void setAccountTemplate(AccountTemplateInter accountTemplate) {
		this.accountTemplate = accountTemplate;
	}

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

	public void setAuditService(AuditService auditService) {
		this.auditService = auditService;
	}

	public AuditOperandType getAuditOperandType() {
		return this.auditService.getAuditOperandType(AUDIT_OPERAND_CLASS,
				ACTION_FLAG_IDCARD_AUTHENTICATION);
	}

	/**
	 * 根据审核状态获取对应的认证状态，目的是为了避免认证模块与审核模块的状态不一致
	 * 
	 * @param auditStatus
	 *            审核状态
	 * @return 指定审核状态对应的认证状态
	 */
	private String getAuthenticationStatusByAuditStatus(AuditStatus auditStatus) {
		if (auditStatus == AuditStatus.STATUS_SUBMITTED) {
			return Constant.AUTHENTICATION_STATUS_SUBMITTED;
		}
		if (auditStatus == AuditStatus.STATUS_REJECTED) {
			return Constant.AUTHENTICATION_STATUS_UNPASS;
		}
		if (auditStatus == AuditStatus.STATUS_FINAL) {
			return Constant.AUTHENTICATION_STATUS_PASS;
		}
		return Constant.AUTHENTICATION_STATUS_TOPUBMITTED;
	}

	/**
	 * 提交身份证认证请求 正面和背面图片均不空时为上传二代证图片； 正面图片为空时为上传一代证图片； 正面和背面图片均为空时为传真身份证复印件。
	 */
	public boolean submitIdcard(Account account, String idcardName,
			String idcardNo, String authenticationMethod,
			InputStream idcardPhotoStream, InputStream idcardPhotoBackStream)
			throws Exception {
		try {
			AuditOperandType aot = getAuditOperandType();
			// 若本操作未设置审核规则
			if (!this.auditService.requiredSystemAudit(aot)) {
				return false;
			}
			long accountId = account.getId().longValue();
			this.auditService.submit(aot, accountId, account);
			account.setIdType(Constant.ID_TYPE_IDCARD);
			account.setAuthenticationName(idcardName);// 用户姓名
			account.setAuthenticationIdCode(idcardNo);// 身份证卡号
			AuditStatus auditStatus = this.auditService.getCurrentAuditStatus(aot,
					accountId);
			setAuthenticationStatus(account, authenticationMethod,
					getAuthenticationStatusByAuditStatus(auditStatus));
			account.setUpdateTime(new Date());
			if (idcardPhotoStream == null && idcardPhotoBackStream == null) {
				this.accountTemplate.updateAccount(account);
			} else {
				this.accountTemplate.saveOrUpdateAccount(account, null,
						idcardPhotoStream, idcardPhotoBackStream);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	public boolean feasibleBankCardAuthentication(Account account) {
		return this.transactionTemplate.getCountOfBankCardTransactions(account) > 0;
	}

	private String getAuthenticationStatus(Account account, String statusName) {
		AuthenticationStatus authenticationStatus = AuthenticationStatus
				.getInstance(account.getAuthenticationStatus());
		return authenticationStatus.getStatus(statusName);
	}

	private Account setAuthenticationStatus(Account account, String statusName,
			String status) {
		AuthenticationStatus authenticationStatus = AuthenticationStatus
				.getInstance(account.getAuthenticationStatus());
		authenticationStatus.setStatus(statusName, status);
		account.setAuthenticationStatus(authenticationStatus.toString());
		return account;
	}

	public String getBankCardAuthenticationStatus(Account account) {
		String status = getAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_BANK_CARD);
		if (status == null || status.length() == 0)
			status = Constant.AUTHENTICATION_STATUS_UNPASS;
		return status;
	}

	public Account setBankCardAuthenticationStatus(Account account,
			String status) {
		if (status == null || status.length() == 0)
			status = Constant.AUTHENTICATION_STATUS_UNPASS;
		return setAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_BANK_CARD, status);
	}

	public String getMobileTelAuthenticationStatus(Account account) {
		String status = getAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_MOBILE_TEL);
		if (status == null || status.length() == 0)
			status = Constant.AUTHENTICATION_STATUS_UNPASS;
		return status;
	}

	public Account setMobileTelAuthenticationStatus(Account account,
			String status) {
		if (status == null || status.length() == 0)
			status = Constant.AUTHENTICATION_STATUS_UNPASS;
		return setAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_MOBILE_TEL, status);
	}

	public String getIdcardAuthenticationStatus(Account account) {
		return getAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_IDCARD);
	}

	public Account setIdcardAuthenticationStatus(Account account, String status) {
		return setAuthenticationStatus(account,
				Constant.AUTHENTICATION_METHOD_IDCARD, status);
	}

	public boolean authenticatableIdcardNo(Account account, String idcardNo) {
		Long accountId = account.getId();
		List accounts = this.accountTemplate.getAccountListByIdcardNo(idcardNo);
		for (int i = 0; i < accounts.size(); i++) {
			Account a = (Account) accounts.get(i);
			String status = getIdcardAuthenticationStatus(a);
			if (!a.getId().equals(accountId)
					&& (Constant.AUTHENTICATION_STATUS_SUBMITTED.equals(status) || Constant.AUTHENTICATION_STATUS_PASS
							.equals(status))) {
				return false;
			}
		}
		return true;
	}

	public boolean passIdcardNoAuthentication(Account account) {
		String idcardNoStatus = getIdcardAuthenticationStatus(account);
		return Constant.AUTHENTICATION_STATUS_PASS.equals(idcardNoStatus);
	}

	/**
	 * 提交企业结算账户请求
	 * 
	 */
	public boolean submitClearAmount(Account account,
			String authenticationMethod) throws Exception {
		AuditOperandType aot = getAuditOperandClearAmountType();
		// 若本操作未设置审核规则
		if (!this.auditService.requiredSystemAudit(aot)) {
			return false;
		}
		long accountId = account.getId().longValue();
		this.auditService.submit(aot, accountId, account,true);
		AuditStatus auditStatus = this.auditService.getCurrentAuditStatus(aot,
				accountId);
		setAuthenticationStatus(account, authenticationMethod,
				getAuthenticationStatusByAuditStatus(auditStatus));
		account.setUpdateTime(new Date());
		this.accountTemplate.updateAccount(account);
		return true;
	}
	
	public AuditOperandType getAuditOperandClearAmountType() {
		return this.auditService.getAuditOperandType(AUDIT_CLEARAMOUNT_CLASS,
				ACTION_FLAG_CLEARAMOUNT_AUTHENTICATION);
	}
}
